package com.zhaokuner.springcloudconfigserver.webhook;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zhaokuner.springcloudconfigserver.utils.MyBeanUtils;
import com.zhaokuner.springcloudconfigserver.utils.MyDateUtils;
import com.zhaokuner.springcloudconfigserver.zk.CuratorClient;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * Description:webhooks数据处理
 * <p>
 * Copyright: 2018-现在 北京掌通未来科技有限公司
 * <p>
 *
 * @author 赵希坤 zhaoxikun
 * @date 2020/7/24 15:12
 */
@Service
@Log4j2
public class WebHooksService {
    @Autowired
    private CuratorClient curatorClient;

    private final String xiegang = "/";
    private final String suffixYml = ".yml";
    private final String suffixProperties = ".properties";

    /**
     * 去除 .yml .properties
     *
     * @param fileName 配置文件名称
     * @return
     */
    public String dealFileName(String fileName) {
        if (fileName.endsWith(suffixYml) || fileName.endsWith(suffixProperties)) {
            return fileName.substring(0, fileName.lastIndexOf("."));
        }
        return fileName;
    }

    public void zk(HashMap<String, WebHookModel> map) {
        log.info("******************** git files size {} names {}", map.size(), map.keySet());
        map.forEach((k, v) -> {
            Object result = null;
            List<String> list = new ArrayList<>();
            list.add(MyDateUtils.getLocalDateTime(v.getPushTimestamp()).format(MyDateUtils.normalDateTimeFormatter));
            list.add(v.getCommitId());
            list.add(v.getMessage());
            String value = JSON.toJSONString(list);
            try {
                result = curatorClient.change(v.getBranch(), k, value);
            } catch (Exception e) {
                log.error("******************** zk publish error " + k + " " + JSON.toJSONString(v), e);
                try {
                    result = curatorClient.change(v.getBranch(), k, value);
                } catch (Exception ee) {
                    log.error("******************** zk publish error too " + k + " " + JSON.toJSONString(v), ee);
                }
            }
            if (null != result) {
                log.info("******************** zk publish success {}", result);
            }
        });
    }

    public HashMap<String, WebHookModel> gitee(JSONObject obj) {
        HashMap<String, WebHookModel> map = new HashMap<>(8);
        WebHookModel root = new WebHookModel();
        if (null == obj) {
            return map;
        }
        //提交
        JSONArray commits = obj.getJSONArray("commits");
        if (null == commits || commits.isEmpty()) {
            return map;
        }

        String branch = obj.getString("ref");
        if (null == branch) {
            branch = "";
        } else {
            if (!branch.endsWith(xiegang)) {
                branch = branch.substring(branch.lastIndexOf(xiegang) + 1);
            }
        }
        root.setBranch(branch);
        root.setCommitId(obj.getString("after"));
        root.setRepositoryName(obj.getJSONObject("repository").getString("name"));
        root.setGitHttpUrl(obj.getJSONObject("repository").getString("git_http_url"));
        root.setPushTimestamp(Long.valueOf(obj.getString("timestamp")));

        for (int i = 0; i < commits.size(); i++) {
            JSONObject commit = commits.getJSONObject(i);
            List<WebHookModel> list = dealCommits(root, commit);
            for (WebHookModel model : list) {
                //以提交时间大的为准
                map.merge(dealFileName(model.getConfigFileName()), model, (o, n) -> o.getCommitTimestamp() > n.getCommitTimestamp() ? o : n);
            }
        }
        return map;
    }

    private List<WebHookModel> dealCommits(WebHookModel root, JSONObject commit) {
        //因为有可能一次提交多个配置文件
        List<WebHookModel> list = new ArrayList<>();
        WebHookModel model = new WebHookModel();
        MyBeanUtils.copy(root, model);
        model.setCommitId(commit.getString("id"));
        model.setMessage(commit.getString("message"));
        model.setCommitTimestamp(timestamp(commit.getString("timestamp")));
        model.setCommitterName(commit.getJSONObject("committer").getString("name"));
        model.setCommitterEmail(commit.getJSONObject("committer").getString("email"));
        JSONArray modified = commit.getJSONArray("modified");
        for (int i = 0; i < modified.size(); i++) {
            WebHookModel modifyFile = new WebHookModel();
            MyBeanUtils.copy(model, modifyFile);
            modifyFile.setConfigFileName(modified.getString(i));
            list.add(modifyFile);
        }
        return list;
    }

    private Long timestamp(String timeString) {
        //2020-07-24T17:05:14+08:00
        return LocalDateTime.parse(timeString.substring(0, timeString.indexOf("+")) + ".000")
                .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

}
